package cn.wolfcode.redis.service.impl;

import cn.wolfcode.redis.service.ISecurityRedisService;
import cn.wolfcode.redis.util.RedisKeys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class SecurityRedisService implements ISecurityRedisService {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public boolean isAllowBrush(String key) {
        if (!StringUtils.hasLength(key)) {
            return false;
        }
        redisTemplate.opsForValue().setIfAbsent(key, "10", RedisKeys.BRUSH_PROOF.getTime(), TimeUnit.SECONDS);
        return redisTemplate.opsForValue().decrement(key) >= 0;
    }

    /**
     * 判断是不是黑名单
     *
     * @param ip
     * @return
     */
    @Override
    public boolean inBlackList(String ip) {
        String key = RedisKeys.BLACK_LIST.join(ip);
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    @Override
    public boolean isAllowBrush(int time, int count, TimeUnit unit, String key) {
        if (!StringUtils.hasLength(key)) {
            return false;
        }
        redisTemplate.opsForValue().setIfAbsent(key, String.valueOf(count), time, unit);
        return redisTemplate.opsForValue().decrement(key) >= 0;
    }

    @Override
    public void addIllegalCount(String ip) {
        if (!StringUtils.hasLength(ip)) {
            return;
        }
        redisTemplate.opsForValue().setIfAbsent(RedisKeys.ILLEGAL_COUNT.join(ip), "0");
        redisTemplate.opsForValue().increment(RedisKeys.ILLEGAL_COUNT.join(ip));
        // 违规三次加入黑名单
        if (Integer.parseInt(redisTemplate.opsForValue().get(RedisKeys.ILLEGAL_COUNT.join(ip))) >= 3) {
            add2BlackList(ip);
            // 然后清除统计数据
            redisTemplate.delete(RedisKeys.ILLEGAL_COUNT.join(ip));
        }
    }

    @Override
    public boolean isAllowBrushReg(String key) {
        if (!StringUtils.hasLength(key)) {
            return false;
        }
        redisTemplate.opsForValue().setIfAbsent(key, "3", 1, TimeUnit.MINUTES);
        return Integer.parseInt(redisTemplate.opsForValue().get(key)) > 0;
    }

    @Override
    public void addRegCount(String key) {
        redisTemplate.opsForValue().setIfAbsent(key, "3", 1, TimeUnit.SECONDS);
    }

    private void add2BlackList(String ip) {
        // 先这么做，之后用布隆过滤器优化
        redisTemplate.opsForValue().set(RedisKeys.BLACK_LIST.join(ip), "", RedisKeys.BLACK_LIST.getTime(), TimeUnit.SECONDS);
    }
}

